Skip to content

Conversation

@dimitri-yatsenko
Copy link
Member

@dimitri-yatsenko dimitri-yatsenko commented Jan 22, 2026

Summary

Implements support for singleton tables — tables with empty primary keys that can hold at most one row. This feature was described in the 2018 DataJoint paper and proposed in #113.

Syntax

@schema
class Config(dj.Lookup):
    definition = """
    # Global configuration
    ---
    setting1 : varchar(100)
    setting2 : int32
    """

A definition with no attributes before --- creates a singleton table.

Implementation

  • Uses a hidden _singleton attribute of type bool as the primary key
  • The attribute is automatically created and populated with DEFAULT TRUE
  • Excluded from heading.attributes, fetch() results, and join matching
  • Visible heading.primary_key returns [] (empty)
  • Works with both MySQL and PostgreSQL (adapter-specific boolean literals)

Changed Files

  • src/datajoint/declare.py - Singleton table creation logic
  • src/datajoint/adapters/base.py - Add boolean_true_literal property
  • src/datajoint/adapters/postgres.py - PostgreSQL-specific boolean literal
  • tests/integration/test_declare.py - Comprehensive test coverage

Behavior

Operation Result
Insert without key Works - auto-populates _singleton=True
Second insert Raises DuplicateError
fetch1() Returns the single row (without _singleton)
heading.primary_key Returns [] (empty visible PK)

Use Cases

  • Global configuration settings
  • Pipeline parameters
  • Summary statistics
  • State tracking (e.g., current term in a university database)

Test Plan

  • test_singleton_declaration - Table creates with hidden _singleton attribute
  • test_singleton_insert_and_fetch - Insert/fetch work without specifying key
  • test_singleton_uniqueness - Second insert raises DuplicateError
  • test_singleton_with_multiple_attributes - Works with multiple secondary attrs
  • test_singleton_describe - Describe shows singleton nature

Closes #113

🤖 Generated with Claude Code

Implements support for singleton tables - tables with empty primary keys
that can hold at most one row. This feature was described in the 2018
DataJoint paper and proposed in issue #113.

Syntax:
```python
@Schema
class Config(dj.Lookup):
    definition = """
    ---
    setting : varchar(100)
    """
```

Implementation uses a hidden `_singleton` attribute of type `bool` as
the primary key. This attribute is automatically created and excluded
from user-facing operations (heading.attributes, fetch, join matching).

Closes #113

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot added enhancement Indicates new improvements feature Indicates new features labels Jan 22, 2026
dimitri-yatsenko added a commit to datajoint/datajoint-docs that referenced this pull request Jan 22, 2026
- Add section 2.5 "Singleton Tables (Empty Primary Keys)" to table-declaration.md
- Update university tutorial with CurrentTerm singleton example
- Remove deprecated `___` separator mention (only `---` is supported)

Related to datajoint/datajoint-python#1341
Closes datajoint/datajoint-python#113

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dimitri-yatsenko and others added 2 commits January 22, 2026 14:57
Add boolean_true_literal adapter property to generate correct
DEFAULT value for the hidden _singleton attribute:
- MySQL: DEFAULT 1 (bool maps to tinyint)
- PostgreSQL: DEFAULT TRUE (native boolean)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dimitri-yatsenko dimitri-yatsenko changed the base branch from pre/v2.0 to pre/v2.1 January 22, 2026 21:22
dimitri-yatsenko and others added 3 commits January 22, 2026 15:31
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated translate_attribute() to accept optional adapter parameter
- PostgreSQL adapter's json_path_expr() now handles array notation and type casting
- Pass adapter to translate_attribute() in condition.py, declare.py, expression.py

This enables basic JSON operations to work on both MySQL and PostgreSQL.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MySQL accepts TRUE as a boolean literal (alias for 1), so we can
use TRUE universally instead of having backend-specific literals.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@MilagrosMarin MilagrosMarin merged commit e0a7c6d into pre/v2.1 Jan 23, 2026
7 of 8 checks passed
@MilagrosMarin MilagrosMarin deleted the feat/singleton-tables branch January 23, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Indicates new improvements feature Indicates new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants